package analyzer.protocal;

import java.io.FileInputStream;
import java.io.IOException;

/**
 * 0----------------16---------------31 bit
 * version(4) HeaderLength(4) DSField(8) TotalLength(16)
 * Identification(16) Flags(3) FragmentOffset(13)
 * TimeToLive(8) Protocol(8) HeaderChecksum(16)
 * Source IP Address (16)
 * Destination IP Address(16)
 */

public class IP {
    public static void analyze(FileInputStream in)
    {
        verionAndHeaderLength(in);
        diffServices(in);
        totalLength(in);
        identification(in);
        flagsAndFragOffset(in);
        timeToLive(in);
        protocol(in);
        checkSum(in);
        srcIP(in);
        destIP(in);
    }
    private static void verionAndHeaderLength(FileInputStream in)
    {
        byte[] b = new byte[1];
        try {
            in.read(b);
            int headerLength= b[0]&0x0f;
            int version = (b[0]>>4)&0x0f;
            System.out.println("version: " + version + ", header length:" + headerLength);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    private static void diffServices(FileInputStream in)
    {
        byte[] b = new byte[1];
        try {
            in.read(b);
            String service = String.format("%02x:", b[0]);
            System.out.println("differentiated services: " + service);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    private static void totalLength(FileInputStream in)
    {
        byte[] b = new byte[2];
        try {
            in.read(b);
            int len = b[1]&0xff;
            len += 256 * (b[0]&0xff);
            System.out.println("IP packet length: " + len);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    private static void identification(FileInputStream in)
    {
        byte[] b = new byte[2];
        try {
            in.read(b);
            int id = b[1]&0xff;
            id += 256 * (b[0]&0xff);
            System.out.println("IP packet identification: " + id);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    private static void flagsAndFragOffset(FileInputStream in)
    {
        byte[] b = new byte[2];
        try {
            in.read(b);
            int fragId = b[1]&0xff;
            fragId += 256 * (b[0]&0x1f);
            fragId *= 8;
            int flag = b[0] >> 5;
            System.out.println("IP packet fragment identification: " + fragId);
            System.out.println("IP packet flag: " + flag);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    private static void timeToLive(FileInputStream in)
    {
        byte[] b = new byte[1];
        try {
            in.read(b);
            int ttl = b[0]&0xff;
            System.out.println("IP packet time to live: " + ttl);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    private static void protocol(FileInputStream in)
    {
        //tcp:6 udp:17 icmp:1 igmp:2
        byte[] b = new byte[1];
        try {
            in.read(b);
            int protocol = b[0]&0xff;
            System.out.println("Protocol of IP packet data: " + protocol);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    private static void checkSum(FileInputStream in)
    {
        byte[] b = new byte[2];
        try {
            in.read(b);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    private static void srcIP(FileInputStream in)
    {
        byte[] b = new byte[4];
        try {
            in.read(b);
            String ip = "" + (b[0]&0xff) + "." + (b[1]&0xff) + "." + (b[2]&0xff) + "." + (b[3]&0xff);
            System.out.println("Source IP: " + ip);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    private static void destIP(FileInputStream in)
    {
        byte[] b = new byte[4];
        try {
            in.read(b);
            String ip = "" + (b[0]&0xff) + "." + (b[1]&0xff) + "." + (b[2]&0xff) + "." + (b[3]&0xff);
            System.out.println("Destination IP: " + ip);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
